﻿#region License
// (c) Intergen.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MediaWiki.Office.Packaging;

namespace MediaWiki.Office.Model
{
  public abstract class Content
  {
    private Content _parent;

    public Content Parent
    {
      get { return _parent; }
      set { _parent = value; }
    }

    public virtual Document MainDocument
    {
      get
      {
        if (Parent == null)
          throw new Exception("Could not get document. Content parent is null.");

        return Parent.MainDocument;
      }
    }

    public virtual IPackagePart Part
    {
      get { return _parent.Part; }
    }

    public Content(Content parent)
    {
      _parent = parent;
    }

    public Uri GetResolvedTarget(string relationshipId)
    {
      Uri targetUri = GetTarget(relationshipId);

      return ResolveTarget(targetUri);
    }

    public Uri GetTarget(string relationshipId)
    {
      if (relationshipId == null)
        return null;

      PackageRelationship relationship = Part.Relationships.Where(r => r.Id == relationshipId).SingleOrDefault();

      return (relationship != null) ? relationship.TargetUri : null;
    }

    public Uri ResolveTarget(Uri targetUri)
    {
      return PackageUriHelper.ResolvePartUri(Part.Uri, targetUri);
    }

    public static Table GetParentTable(Content content)
    {
      if (content == null)
        throw new ArgumentNullException("content");

      Content parent = content;
      while ((parent = parent.Parent) != null)
      {
        if (parent is Table)
          return (Table)parent;
      }

      return null;
    }

    /// <summary>
    /// Gets the immediate parent cell of the given content.
    /// </summary>
    /// <param name="content">The content.</param>
    /// <returns></returns>
    public static TableCell GetParentCell(Content content)
    {
      if (content == null)
        throw new ArgumentNullException("content");

      Content parent = content;
      while ((parent = parent.Parent) != null)
      {
        if (parent is TableCell)
          return (TableCell)parent;
      }

      return null;
    }

    /// <summary>
    /// Gets the immediate parent row of the given content.
    /// </summary>
    /// <param name="content">The content.</param>
    /// <returns></returns>
    public static TableRow GetParentRow(Content content)
    {
      if (content == null)
        throw new ArgumentNullException("content");

      Content parent = content;
      while ((parent = parent.Parent) != null)
      {
        if (parent is TableRow)
          return (TableRow)parent;
      }

      return null;
    }

    /// <summary>
    /// Gets the document style matching the given styleId.
    /// </summary>
    /// <param name="parent">The parent.</param>
    /// <param name="styleId">The style id.</param>
    /// <returns></returns>
    public static Style GetStyle(Content parent, string styleId)
    {
      if (parent == null)
        throw new Exception("Could not get Style as parent content is not defined.");

      if (styleId == null)
        return null;

      if (parent.MainDocument.Styles.Contains(styleId))
        return parent.MainDocument.Styles[styleId];

      return null;
    }
  }
}